#!/usr/bin/env python3
"""
面向 rubygem-ZenTest 软件的 MCP Server

MCP tools 列表：
1. zentest_unit_diff - 执行 zentest 和 unit_diff 组合命令，用于测试文件差异分析
   参数：test_file, target_file, unit_diff_options
   返回：统一的命令执行结果 JSON

2. zentest_multigem - 执行 multigem 命令，用于多版本 gem 测试
   参数：无
   返回：统一的命令执行结果 JSON

3. zentest_multiruby - 执行 multiruby 命令，用于多版本 ruby 测试
   参数：无
   返回：统一的命令执行结果 JSON

4. zentest_basic - 执行基本 zentest 命令，包括帮助、版本和文件扫描
   参数：files, show_help, show_version
   返回：统一的命令执行结果 JSON

5. zentest_advanced - 执行高级 zentest 命令，支持各种选项
   参数：files, extract_only, test_only, rails_file
   返回：统一的命令执行结果 JSON

6. autotest_help - 执行 autotest 帮助命令
   参数：无
   返回：统一的命令执行结果 JSON

7. multiruby_setup_operations - 执行 multiruby_setup 的各种操作
   参数：operation, target
   返回：统一的命令执行结果 JSON
"""

import subprocess
import shlex
from typing import List, Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("ZenTest MCP Server")

@mcp.tool()
def zentest_unit_diff(test_file: str, target_file: str, unit_diff_options: str = "") -> dict:
    """
    执行 zentest 和 unit_diff 组合命令，用于测试文件差异分析
    
    参数:
        test_file: 测试文件路径
        target_file: 目标文件路径
        unit_diff_options: unit_diff 的选项，如 -b, -c, -k, -u, -p 等
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        # 构建命令
        cmd = f"zentest {shlex.quote(test_file)} {shlex.quote(target_file)} | unit_diff {unit_diff_options}"
        
        # 执行命令
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": f"zentest {test_file} {target_file} | unit_diff {unit_diff_options}",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def zentest_multigem() -> dict:
    """
    执行 multigem 命令，用于多版本 gem 测试
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        cmd = "multigem"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": "multigem",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def zentest_multiruby() -> dict:
    """
    执行 multiruby 命令，用于多版本 ruby 测试
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        cmd = "multiruby"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": "multiruby",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def zentest_basic(files: List[str] = None, show_help: bool = False, show_version: bool = False) -> dict:
    """
    执行基本 zentest 命令，包括帮助、版本和文件扫描
    
    参数:
        files: 要扫描的文件列表
        show_help: 是否显示帮助信息
        show_version: 是否显示版本信息
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        cmd_parts = ["zentest"]
        
        if show_help:
            cmd_parts.append("-h")
        elif show_version:
            cmd_parts.append("-v")
        elif files:
            cmd_parts.extend(shlex.quote(f) for f in files)
        else:
            cmd_parts.append("-h")  # 默认显示帮助
        
        cmd = " ".join(cmd_parts)
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd_parts) if 'cmd_parts' in locals() else "zentest",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def zentest_advanced(files: List[str] = None, extract_only: bool = False, 
                    test_only: bool = False, rails_file: str = None) -> dict:
    """
    执行高级 zentest 命令，支持各种选项
    
    参数:
        files: 要扫描的文件列表
        extract_only: 是否只提取方法 (-e 选项)
        test_only: 是否只生成测试 (-t 选项)
        rails_file: Rails 文件路径 (-r 选项)
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        cmd_parts = ["zentest"]
        
        if extract_only:
            cmd_parts.append("-e")
        elif test_only:
            cmd_parts.append("-t")
        elif rails_file:
            cmd_parts.extend(["-r", shlex.quote(rails_file)])
        
        if files:
            cmd_parts.extend(shlex.quote(f) for f in files)
        
        cmd = " ".join(cmd_parts)
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd_parts) if 'cmd_parts' in locals() else "zentest",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def autotest_help() -> dict:
    """
    执行 autotest 帮助命令
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        cmd = "autotest --help"
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": "autotest --help",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def multiruby_setup_operations(operation: str, target: str = "") -> dict:
    """
    执行 multiruby_setup 的各种操作
    
    参数:
        operation: 操作类型，如 build, clean, list, rm, tags, rubygems:merge, update:rubygems, update
        target: 操作目标，如版本号或标签
    
    返回:
        {
            "success": bool,      # 命令是否成功执行
            "command": str,       # 执行的完整命令
            "exit_code": int,     # 命令退出码
            "stdout": str,        # 标准输出
            "stderr": str         # 标准错误
        }
    """
    try:
        cmd_parts = ["multiruby_setup"]
        
        if operation in ["-h", "--help"]:
            cmd_parts.append(operation)
        else:
            cmd_parts.append(operation)
            if target:
                cmd_parts.append(shlex.quote(target))
        
        cmd = " ".join(cmd_parts)
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
        
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd_parts) if 'cmd_parts' in locals() else "multiruby_setup",
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

if __name__ == "__main__":
    mcp.run()